﻿using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ZhuXingFamilys
{
    public partial class FurnitureFamilyDragAndDropForm : System.Windows.Forms.Form
    {
        public static BuiltInCategory FamilyCategory
        {
            get
            {
                return BuiltInCategory.OST_Furniture;
            }
        }

        private static FurnitureFamilyDragAndDropForm s_form;
        public static FurnitureFamilyDragAndDropForm GetTheForm(Document document)
        {
            if (s_form == null)
            {
                s_form = new FurnitureFamilyDragAndDropForm(document);
            }
            s_form.UpdateLoadedFamilies();
            return s_form;
        }

        /// <summary>
        /// Display class for the external family file listbox.
        /// </summary>
        private class FamilyListBoxMember
        {
            public string FullPath;
            public string Name;
            public FamilyListBoxMember(string fullPath, string name)
            {
                FullPath = fullPath;
                Name = name;
            }

            public override String ToString()
            {
                return Name;
            }
        }

        private Document m_document;

        /// <summary>
        /// Construct and populate the form.
        /// </summary>
        /// <param name="document"></param>
        private FurnitureFamilyDragAndDropForm(Document document)
        {
            InitializeComponent();
            m_document = document;

            UpdateFamilyFileList();
        }
        //更新新载入族列表
        private void UpdateFamilyFileList()
        {
            // Visit each Revit library looking for Furniture families
            IDictionary<String, String> libraryPaths = m_document.Application.GetLibraryPaths();
            foreach (String libraryPath in libraryPaths.Values)
            {
                foreach (String directory in Directory.EnumerateDirectories(libraryPath, "*结构预制", SearchOption.AllDirectories))
                {
                    foreach (String familyFile in Directory.EnumerateFiles(directory, "*.rfa", SearchOption.AllDirectories))
                    {
                        // Add each Furniture family to the listbox
                        String fileName = Path.GetFileName(familyFile);
                        FamilyListBoxMember member = new FamilyListBoxMember(familyFile, fileName);
                        listBox1.Items.Add(member);
                    }
                }
            }
        }

        //更新载入项目族列表
        private void UpdateLoadedFamilies()
        {
            ListView.ListViewItemCollection collection = listView1.Items;
            collection.Clear();

            // Setup list view with loaded families
            ImageList imageList = new ImageList();
            Size size = new Size(50, 50);
            imageList.ImageSize = size;



            FilteredElementCollector collector = new FilteredElementCollector(m_document);
            collector.OfCategory(FamilyCategory);
            collector.OfClass(typeof(FamilySymbol));

            foreach (FamilySymbol familySymbol in collector.Cast<FamilySymbol>())
            {
                ListViewItem item = new ListViewItem();
                item.Tag = familySymbol.Id;
                item.Text = familySymbol.Family.Name + "::" + familySymbol.Name;
                item.ToolTipText = "Drag to place instances of " + item.Text + " in the active document.";

                Bitmap bitmap = familySymbol.GetPreviewImage(size);

                if (bitmap != null)
                {
                    imageList.Images.Add(bitmap);
                    int index = imageList.Images.Count - 1;
                    item.ImageIndex = index;
                }

                collection.Add(item);
            }

            listView1.LargeImageList = imageList;
        }

        // Drag action from list view
        private void listView_MouseMove(object sender, MouseEventArgs e)
        {
            if (MouseButtons == MouseButtons.Left)
            {
                ListViewItem selectedItem = this.listView1.SelectedItems.Cast<ListViewItem>().FirstOrDefault<ListViewItem>();

                if (selectedItem != null)
                {
                    // Use custom Revit drag and drop behavior
                    LoadedFamilyDropHandler myhanlder = new LoadedFamilyDropHandler();
                    UIApplication.DoDragDrop(selectedItem.Tag, myhanlder);
                }
            }
        }

        // Drag action from list box
        private void listBox1_MouseMove(object sender, MouseEventArgs e)
        {
            if (MouseButtons == MouseButtons.Left)
            {
                FamilyListBoxMember member = (FamilyListBoxMember)listBox1.SelectedItem;

                // Use standard Revit drag and drop behavior
                List<String> data = new List<String>();
                data.Add(member.FullPath);
                UIApplication.DoDragDrop(data);
                
            }
        }

        private void FurnitureFamilyDragAndDropForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            s_form = null;
        }

        private void listView1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void listView2_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
    }


    /// <summary>
    /// Custom handler for placement of loaded family types
    /// </summary>
    public class LoadedFamilyDropHandler : IDropHandler
    {
        public void Execute(UIDocument document, object data)
        {
            try
            {
                ElementId familySymbolId = (ElementId)data;

                FamilySymbol symbol = document.Document.GetElement(familySymbolId) as FamilySymbol;

                if (symbol != null)
                {
                    document.PromptForFamilyInstancePlacement(symbol);
                }
            }
            catch (Autodesk.Revit.Exceptions.OperationCanceledException)
            {
                // user canceled the operation
            }
        }

      
    }
}
